In dieser Übung wollen wir uns die Signale nochmal etwas genauer anschauen und prüfen,
welche Fallstricke sich alles ergeben, wenn wir Nebenläufigkeit durch Signale haben.
Die Sache ist nämlich, dass durch die Ausführung der Signalbehandlung plötzlich Nebenläufigkeit
in unser Programm kommt.
Und in dem Fall müssen wir darauf aufpassen, dass diese Nebenläufigkeit nicht zu Inkonsistenzen
im Programm führt.
Darauf müssen wir immer besonders acht geben, falls die Signalbehandlung auf denselben
Zustand zugreift wie der Rest des Programms.
Dies wollen wir uns nun an einem kleinen Beispiel verdeutlichen.
Im ersten Schaubild haben wir eine verkettete Liste, die aus sechs Elementen besteht.
Diese halten jeweils eine Referenz auf das Nachfolgeelement.
Nun stellen wir uns vor, dass wir im Hauptprogramm einfach durch die Liste etablieren und uns
jedes Listeelement anschauen.
Dabei halten wir die Adresse des aktuellen Listeelement in einer lokalen Variable.
Nun kann es vorkommen, dass wir während des Etablierens unterbrochen werden und zwar durch
Eintreffen eines Signals.
Zum Beispiel werden wir gerade am dritten Element sind.
Wenn nun die Signalbehandlung beispielsweise ebenfalls auf der Liste arbeitet und dabei
das dritte und vierte Element aus der Liste herauslöscht, haben wir ein Problem.
Denn sobald die Signalbehandlung wieder zurückkehrt, befinden wir uns wieder im Hauptprogramm,
dass am dritten Element ist, das aber nicht mehr Teil der Liste ist.
Wir haben aber nicht mitbekommen, dass das Element aus der Liste ausgetragen wurde.
Erschwerend kommt nun hinzu, dass auch die Signalbehandlung nicht dafür sorgen kann,
dass die unterbrochene Ausführung wieder in einen konsistenten Zustand versetzt werden
kann.
Die Signalbehandlung kann also die Daten der unterbrochenen Ausführung nicht wieder heilen.
Dieses Problem wollen wir jetzt genauer analysieren.
Und dabei stellen sich zunächst einmal zwei grundsätzliche Fragen.
Die erste dabei ist, welche Art der Nebenläufigkeit liegt eigentlich vor?
Wir haben hier eine asymmetrische, da hier zwei nicht gleichberechtigte Kontrollflüsse
vorliegen.
Wir haben zum einen das Hauptprogramm, das jederzeit durch die Signalbehandlung unterbrochen
werden kann.
Und auf der anderen Seite haben wir die Signalbehandlung selbst, die nicht mehr unterbrochen werden
kann.
Diese wird mit einer Run-to-Completion-Semantik ausgeführt.
Die zweite Fragestellung beschäftigt sich damit, wie wir mit dem Problem umgehen können.
Es fragt sich also, welche Art der Synchronisation hier verwendet werden kann.
Zur Auswahl stehen einmal die mehrseitige und die einseitige Synchronisation.
In diesem Fall entscheiden wir uns für die einseitige Synchronisation.
Wir haben nämlich einen kritischen Abschnitt, nämlich den Zugriff auf die Liste, den wir
schützen wollen.
Diesen müssen wir nur vor der Ausführung der Signalbehandlung schützen.
Dies erreichen wir, indem wir die Signalbehandlung solange verzögern, bis wir den kritischen
Abschnitt wieder verlassen haben.
Also können wir das Signal versuchen zu blockieren.
Dabei sollten wir beachten, dass wir das Signal so kurz wie möglich blockieren, um das Risiko
des Verlusts eines Signals aus dem Weg zu gehen.
Zwar werden Signale, die auftreten, während sie blockiert sind, vermerkt, d.h. man weiß,
dass so ein Signal eingetroffen ist, jedoch kann nicht festgestellt werden, wie oft dieses
Zugänglich über
Offener Zugang
Dauer
00:12:00 Min
Aufnahmedatum
2020-12-01
Hochgeladen am
2020-12-01 16:10:39
Sprache
de-DE